#ifndef ION_UTILS
#define ION_UTILS
#include <unistd.h>

enum ion_heap_type {
	ION_HEAP_TYPE_SYSTEM,
	ION_HEAP_TYPE_SYSTEM_CONTIG,
	ION_HEAP_TYPE_CARVEOUT,
	ION_HEAP_TYPE_CHUNK,
	ION_HEAP_TYPE_DMA,
	ION_HEAP_TYPE_CUSTOM, /*
			       * must be last so device specific heaps always
			       * are at the end of this enum
			       */
	ION_NUM_HEAPS = 16,
};

#define ION_HEAP_SYSTEM_MASK		((1 << ION_HEAP_TYPE_SYSTEM))
#define ION_HEAP_SYSTEM_CONTIG_MASK	((1 << ION_HEAP_TYPE_SYSTEM_CONTIG))
#define ION_HEAP_CARVEOUT_MASK		((1 << ION_HEAP_TYPE_CARVEOUT))
#define ION_HEAP_TYPE_DMA_MASK		((1 << ION_HEAP_TYPE_DMA))

#define ION_NUM_HEAP_IDS		(sizeof(unsigned int) * 8)
#define ION_FLAG_CACHED 1		
#define ION_FLAG_CACHED_NEEDS_SYNC 2	
struct ion_allocation_data {
	size_t len;
	unsigned int heap_id_mask;
	unsigned int flags;
    uint32_t fd;
    uint32_t unused;
};

struct ion_custom_data {
	unsigned int cmd;
	unsigned long arg;
};

#define ION_IOC_MAGIC		'I'

#define ION_IOC_ALLOC		_IOWR(ION_IOC_MAGIC, 0, \
				      struct ion_allocation_data)

#define ION_IOC_FREE		_IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)

#define ION_IOC_MAP		_IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)

#define ION_IOC_SHARE		_IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)

#define ION_IOC_IMPORT		_IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)

#define ION_IOC_SYNC		_IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data)

#define ION_IOC_CUSTOM		_IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)

#define ION_BIT(nr) (1UL << (nr))

#define ION_HEAP(bit)			ION_BIT(bit)

#define ION_QSECOM_TA_HEAP_ID		ION_BIT(1)
#define ION_CAMERA_HEAP_ID		ION_BIT(30)
#define ION_DISPLAY_HEAP_ID		ION_BIT(3)
#define ION_ADSP_HEAP_ID		ION_BIT(4)
#define ION_AUDIO_ML_HEAP_ID		ION_BIT(5)
#define ION_USER_CONTIG_HEAP_ID		ION_BIT(6)
#define ION_QSECOM_HEAP_ID		ION_BIT(7)
#define ION_AUDIO_HEAP_ID		ION_BIT(8)
#define ION_CP_MM_HEAP_ID		ION_BIT(9)
#define ION_SECURE_HEAP_ID		ION_BIT(10)
#define ION_SECURE_DISPLAY_HEAP_ID	ION_BIT(11)
#define ION_SPSS_HEAP_ID		ION_BIT(14)
#define ION_SECURE_CARVEOUT_HEAP_ID	ION_BIT(15)
#define ION_TUI_CARVEOUT_HEAP_ID	ION_BIT(16)
#define ION_AUDIO_CARVEOUT_HEAP_ID	ION_BIT(17)
#define ION_SYSTEM_HEAP_ID		ION_BIT(25)
#define ION_HEAP_ID_RESERVED		ION_BIT(31)

#define ION_ADSP_HEAP_NAME	"adsp"
#define ION_SYSTEM_HEAP_NAME	"system"
#define ION_MM_HEAP_NAME	"mm"
#define ION_SPSS_HEAP_NAME	"spss"
#define ION_CAMERA_HEAP_NAME    "camera_heap"
#define ION_SECURE_CARVEOUT_HEAP_NAME	"secure_carveout"
#define ION_USER_CONTIG_HEAP_NAME	"user_contig"
#define ION_QSECOM_HEAP_NAME	"qsecom"
#define ION_QSECOM_TA_HEAP_NAME	"qsecom_ta"
#define ION_SECURE_HEAP_NAME	"secure_heap"
#define ION_SECURE_DISPLAY_HEAP_NAME "secure_display"
#define ION_AUDIO_HEAP_NAME    "audio"
#define ION_TUI_CARVEOUT_HEAP_NAME "tui_carveout"
#define ION_DISPLAY_HEAP_NAME "display"
#define ION_AUDIO_ML_HEAP_NAME "audio_ml"

#define ION_HEAP_FLAG_DEFER_FREE (1 << 0)

//Device/firmware specific
#define ION_HEAP_OPS_OBJ_OFF 0x30

#define ION_HEAP_FREELIST_OFF 0x120

#define ION_HEAP_FLAGS_OFF 0xc0

#define ION_HEAP_WAITQUEUE_OFF 0x140

#define ION_HEAP_OPS_OFF 0x2d5f180

uint64_t ion_heap_phys_addr(uint32_t id);

void* map_ion_region(int ion_fd, uint32_t id, size_t len);

uint64_t ion_heap_size(uint32_t id);

void* spray_ion_heap(uint32_t id, size_t size);

int ion_allocate(int ion_fd, uint32_t id, size_t len);

#endif
